/*
 * Synset.groovy
 * Copyright (C) 2008  Young,Fey <fey.young@gmail.com>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.youngfey.wordmaster.wordnet
import edu.smu.tspell.wordnet.SynsetType

class Synset {
    private static final cache = [:]

    final String id
    final SynsetType type
    final String definition
    final List<String> examples
    List<String> forms = []
    def antonymMap = [:]
    def derivativeMap = [:]

    /**
     * 根据给定的form进行查询，并返回所有以form为变体或本体的synset。如books将返回book。
     * @return 所有与form对应的synset
     */
    static final lookup(form) {
        def synsets = []
        WordNetDictionary.getDatabase().getSynsets(form).each {
            synsets << Synset.valueOf(it)
        }
        synsets
    }
    
    private static final valueOf(s) {
        def id = parseId(s)
        if(!cache[id]) {
            initSynset(s, id)
        }
        cache[id]
    }

    private static final initSynset(s, id) {
        cache[id] = new Synset(s)
    }

    static final parseId(s) {
        def str = s.toString()
        str.substring(0, str.indexOf("["))
    }

    private Synset(s) {
        id = parseId(s)
        type = s.getType()
        definition = s.getDefinition()
        examples = s.getUsageExamples().toList()

        def fs = s.getWordForms();
        int size = fs.length;
        def counts = []
        
        size.times { i ->
            def form = fs[i]
            counts[i] = s.getTagCount(form)
            def antonyms = []
            s.getAntonyms(form).each {
                antonyms << it.getWordForm()
            }
            antonymMap[form] = antonyms
            def derivatives = []
            s.getDerivationallyRelatedForms(form).each {
                derivatives << it.getWordForm()
            }
            derivativeMap[form] = derivatives
        }
        size.times { i ->
            int max = -1
            int point = -1
            size.times { j ->
                if (counts[j] > max) {
                    max = counts[j]
                    point = j
                }
            }
            forms[i] = fs[point]
            counts[point] = -1
        }        
    }



    void print() {
        println "\t---\n\t${'Forms:'.padRight(12)}${forms.join(', ')}"
        println "\t${'Type:'.padRight(12)}${getTypeString()}"
        println "\tDefinition: $definition"
        if (examples) println "\tExamples:\n\t            ${examples.join('\n\t            ')}"
    }

    boolean equals(o) {
        o != null && o instanceof Synset && o.getId() == id
    }

    int hashCode() {
        id.hashCode()
    }

    private getTypeString() {
        switch(type) {        
            case SynsetType.ADJECTIVE:
            return "Adjective"
            case SynsetType.ADJECTIVE_SATELLITE:
            return "Adjective Satellite"
            case SynsetType.ADVERB:
            return "Adverb"
            case SynsetType.NOUN:
            return "Noun"
            case SynsetType.VERB:
            return "Verb"
            default:
            return "Unknown Type"
        }
    }
}